using AutoMapper;
using Common;
using Interface;
using Microsoft.AspNetCore.Mvc;
using Model.Dto.Student;
using Model.Entity;
using Model.Vo;

namespace Api.Controllers;

/// <summary>
/// 学生管理控制器
/// </summary>
/// <remarks>
/// 提供学生信息的增删改查接口
/// </remarks>
[ApiController]
[Route("api/students")]
public class StudentController : ControllerBase
{
    private readonly ILogger<StudentController> _logger;
    private readonly IBaseService<Student, StudentVo> _baseService;
    private readonly IStudentService _studentService;
    private readonly IMapper _mapper;

    /// <summary>
    /// 构造函数
    /// </summary>
    /// <param name="baseService">基础服务接口</param>
    /// <param name="studentService">学生服务接口</param>
    /// <param name="mapper">对象映射器</param>
    /// <param name="logger">日志记录器</param>
    public StudentController(IBaseService<Student, StudentVo> baseService, IStudentService studentService, IMapper mapper, ILogger<StudentController> logger)
    {
        _baseService = baseService;
        _studentService = studentService;
        _mapper = mapper;
        _logger = logger;
    }

    /// <summary>
    /// 获取学生列表（支持分页和条件查询）
    /// </summary>
    /// <param name="query">查询参数</param>
    /// <returns>学生列表</returns>
    /// <response code="200">返回学生列表</response>
    /// <response code="500">服务器内部错误</response>
    /// <remarks>
    /// RESTful规范：GET /api/students?page=1&amp;pageSize=10&amp;name=张三&amp;grade=2024级
    /// </remarks>
    [HttpGet]
    public async Task<ActionResult<R<List<StudentVo>>>> GetStudents([FromQuery] StudentQuery query)
    {
        try
        {
            _logger.LogInformation("API调用: 查询学生列表 - 页码: {Page}, 每页数量: {PageSize}", query.Page, query.PageSize);
            var students = await _studentService.GetPageAsync(query);
            return Ok(R<List<StudentVo>>.Success(students));
        }
        catch (ArgumentException ex)
        {
            _logger.LogWarning("查询学生列表失败 - 参数错误: {Message}", ex.Message);
            return BadRequest(R<List<StudentVo>>.Error(ex.Message));
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "查询学生列表失败");
            return StatusCode(500, R<List<StudentVo>>.Error("查询学生列表失败，请稍后重试"));
        }
    }

    /// <summary>
    /// 根据ID获取学生信息
    /// </summary>
    /// <param name="id">学生ID</param>
    /// <returns>学生信息</returns>
    /// <response code="200">返回指定学生信息</response>
    /// <response code="404">未找到学生</response>
    /// <response code="500">服务器内部错误</response>
    /// <remarks>
    /// RESTful规范：GET /api/students/{id}
    /// </remarks>
    [HttpGet("{id:int}")]
    public async Task<ActionResult<R<StudentVo>>> GetStudent(int id)
    {
        try
        {
            _logger.LogInformation("API调用: 获取学生信息 - ID: {Id}", id);
            var student = await _baseService.GetByIdAsync(id);

            return Ok(R<StudentVo>.Success(student));
        }
        catch (ArgumentNullException ex)
        {
            _logger.LogWarning("获取学生信息失败 - 参数为空: {ParamName}", ex.ParamName);
            return BadRequest(R<StudentVo>.Error(ex.Message));
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "获取学生信息失败 - ID: {Id}", id);
            return StatusCode(500, R<StudentVo>.Error("获取学生信息失败，请稍后重试"));
        }
    }


    /// <summary>
    /// 创建新学生
    /// </summary>
    /// <param name="dto">学生添加数据传输对象</param>
    /// <returns>创建的学生信息</returns>
    /// <response code="201">创建成功，返回创建的资源</response>
    /// <response code="400">请求参数错误</response>
    /// <response code="500">服务器内部错误</response>
    /// <remarks>
    /// RESTful规范：POST /api/students
    /// </remarks>
    [HttpPost]
    public async Task<ActionResult<R<StudentVo>>> CreateStudent([FromBody] StudentAdd dto)
    {
        try
        {
            _logger.LogInformation("API调用: 创建学生 - 学号: {StudentNo}", dto.No);
            var student = _mapper.Map<Student>(dto);
            var result = await _baseService.AddAsync(student);
            
            if (result)
            {
                var createdStudent = await _baseService.GetByIdAsync(student.Id);
                return CreatedAtAction(
                    nameof(GetStudent), 
                    new { id = student.Id }, 
                    R<StudentVo>.Success("创建学生成功", createdStudent)
                );
            }
            
            return BadRequest(R<StudentVo>.Error("创建学生失败"));
        }
        catch (Microsoft.Data.SqlClient.SqlException ex) when (ex.Number == 2601 || ex.Number == 2627)
        {
            // 2601: 唯一索引冲突, 2627: 主键冲突
            _logger.LogWarning("创建学生失败 - 学号已存在: {StudentNo}", dto.No);
            return BadRequest(R<StudentVo>.Error($"学号 {dto.No} 已存在，请使用其他学号"));
        }
        catch (BusinessException ex)
        {
            _logger.LogWarning("创建学生失败 - 业务异常: {Message}", ex.Message);
            return BadRequest(R<StudentVo>.Error(ex.Message));
        }
        catch (ArgumentNullException ex)
        {
            _logger.LogWarning("创建学生失败 - 参数为空: {ParamName}", ex.ParamName);
            return BadRequest(R<StudentVo>.Error(ex.Message));
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "创建学生失败 - 学号: {StudentNo}", dto.No);
            return StatusCode(500, R<StudentVo>.Error("创建学生失败，请稍后重试"));
        }
    }

    /// <summary>
    /// 删除学生
    /// </summary>
    /// <param name="id">学生ID</param>
    /// <returns>操作结果</returns>
    /// <response code="204">删除成功，无返回内容</response>
    /// <response code="404">未找到学生</response>
    /// <response code="500">服务器内部错误</response>
    /// <remarks>
    /// RESTful规范：DELETE /api/students/{id}
    /// </remarks>
    [HttpDelete("{id:int}")]
    public async Task<R<string>> DeleteStudent(int id)
    {
        try
        {
            _logger.LogInformation("API调用: 删除学生 - ID: {Id}", id);
            var result = await _baseService.DeleteByIdAsync(id);
            
            if (!result)
            {
                return R<string>.Error("学生不存在");
            }
            
            return R<string>.Success("删除成功");
        }
        catch (ArgumentNullException ex)
        {
            _logger.LogWarning("删除学生失败 - 参数为空: {ParamName}", ex.ParamName);
            return R<string>.Error(ex.Message);
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "删除学生失败 - ID: {Id}", id);
            return R<string>.Error("删除学生失败，请稍后重试");
        }
    }

    /// <summary>
    /// 更新学生信息（完整更新）
    /// </summary>
    /// <param name="id">学生ID</param>
    /// <param name="dto">学生编辑数据传输对象</param>
    /// <returns>更新后的学生信息</returns>
    /// <response code="200">更新成功</response>
    /// <response code="404">未找到学生</response>
    /// <response code="400">请求参数错误</response>
    /// <response code="500">服务器内部错误</response>
    /// <remarks>
    /// RESTful规范：PUT /api/students/{id}
    /// </remarks>
    [HttpPut("{id:int}")]
    public async Task<ActionResult<R<StudentVo>>> UpdateStudent(int id, [FromBody] StudentEdit dto)
    {
        try
        {
            _logger.LogInformation("API调用: 更新学生 - ID: {Id}", id);
            var student = _mapper.Map<Student>(dto);
            student.Id = id;
            var result = await _baseService.UpdateAsync(student);
            
            if (!result)
            {
                return NotFound(R<StudentVo>.Error("学生不存在"));
            }
            
            var updatedStudent = await _baseService.GetByIdAsync(id);
            return Ok(R<StudentVo>.Success("更新成功", updatedStudent));
        }
        catch (Microsoft.Data.SqlClient.SqlException ex) when (ex.Number == 8152)
        {
            // 8152: String or binary data would be truncated
            _logger.LogWarning("更新学生失败 - 数据长度超限: ID {Id}", id);
            return BadRequest(R<StudentVo>.Error("数据长度超出限制，请检查输入内容是否过长"));
        }
        catch (ArgumentNullException ex)
        {
            _logger.LogWarning("更新学生失败 - 参数为空: {ParamName}", ex.ParamName);
            return BadRequest(R<StudentVo>.Error(ex.Message));
        }
        catch (BusinessException ex)
        {
            _logger.LogWarning("更新学生失败 - 业务异常: {Message}", ex.Message);
            return BadRequest(R<StudentVo>.Error(ex.Message));
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "更新学生失败 - ID: {Id}", id);
            return StatusCode(500, R<StudentVo>.Error("更新学生信息失败，请稍后重试"));
        }
    }
}